package com.gmlive.common.gmshare.share

import android.app.Activity
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.text.TextUtils
import androidx.core.content.ContextCompat
import com.gmlive.common.gmshare.R
import com.gmlive.common.gmshare.base.IShareCallback
import com.gmlive.common.gmshare.base.IShareStrategy
import com.gmlive.common.gmshare.bean.ShareEntity
import com.gmlive.common.gmshare.interfaces.ShareConstant
import com.gmlive.common.gmshare.interfaces.ShareConstant.SHARE_STATUS_NOT_SUPPORT
import com.gmlive.common.gmshare.util.BitmapUtil
import com.gmlive.common.gmshare.util.ManifestUtil
import com.tencent.mm.opensdk.constants.Build
import com.tencent.mm.opensdk.modelmsg.*
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import java.io.ByteArrayOutputStream
import java.io.File

/**
 * Author: xs
 * Create on: 2020/06/17
 * Description: _微信分享
 */
object WXShare : IShareStrategy {
    var api: IWXAPI? = null
    private var channel: Int = ShareConstant.SHARE_CHANNEL_WEIXIN_FRIEND
    private var shareEntity: ShareEntity? = null
    private var shareCallback: IShareCallback? = null

    private const val THUMB_SIZE = 250

    private fun initWXApi(activity: Activity?) {
        api = WXAPIFactory.createWXAPI(activity?.applicationContext, ManifestUtil.getWeixinKey(activity))
    }

    override fun share(activity: Activity?, shareChannel: Int?, shareEntity: ShareEntity?, shareCallback: IShareCallback?) {
        this.channel = shareChannel ?: ShareConstant.SHARE_CHANNEL_WEIXIN_FRIEND
        this.shareEntity = shareEntity
        this.shareCallback = shareCallback

        if (null == shareEntity) {
            return
        }

        initWXApi(activity)
        if (!check()) {
            shareCallback?.failed(channel, SHARE_STATUS_NOT_SUPPORT, "未安装微信或者微信版本太低")
            return
        }

        sendMessageToWX(activity)
    }

    private fun sendMessageToWX(context: Activity?) {
        if (!shareEntity?.imgUrl.isNullOrEmpty()) {
            val shareImageUrl = shareEntity?.imgUrl ?: ""
            if (shareImageUrl.startsWith("http")) { // 网络图片
                shareNetImage(context, shareImageUrl)
            } else { // 本地图片
                if (shareEntity?.isShareBigImg == true) { // 分享大图
                    shareBigImage(getLocalBitmap(context, shareImageUrl))
                } else {
                    send(context, getLocalBitmap(context, shareImageUrl))
                }
            }
        } else if (shareEntity?.drawableId != 0) { // 分享本地资源图片
            context?.let {
                var drawable: BitmapDrawable? = null
                try {
                    drawable = shareEntity?.drawableId?.let { id -> ContextCompat.getDrawable(it, id) } as BitmapDrawable?
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                send(context, drawable?.bitmap)
            }
        } else {
            send(context, null)
        }
    }

    private fun shareNetImage(context: Activity?, shareImageUrl: String) {
        BitmapUtil.getResizeBitmapFromUrl(context, shareImageUrl, 100, 100) { bitmap, url ->
            if (shareEntity?.isShareBigImg == true) {
                shareBigImage(bitmap)
            } else {
                send(context, bitmap)
            }
        }
    }

    private fun send(context: Activity?, bitmap: Bitmap?) {
        val req = SendMessageToWX.Req()
        req.transaction = System.currentTimeMillis().toString()
        req.message = buildWXMediaMessage(context, bitmap)
        when (channel) {
            ShareConstant.SHARE_CHANNEL_WEIXIN_FRIEND -> req.scene = SendMessageToWX.Req.WXSceneSession
            ShareConstant.SHARE_CHANNEL_WEIXIN_CIRCLE -> req.scene = SendMessageToWX.Req.WXSceneTimeline
        }

        api?.sendReq(req)
    }

    /**
     * 构建WXMediaMessage
     *
     * @param bitmap
     */
    private fun buildWXMediaMessage(context: Activity?, bitmap: Bitmap?): WXMediaMessage {
        val wxMediaMessage = WXMediaMessage()
        wxMediaMessage.title = shareEntity?.title
        wxMediaMessage.description = shareEntity?.content
        if (TextUtils.isEmpty(shareEntity?.url)) {
            wxMediaMessage.mediaObject = WXTextObject(shareEntity?.content)
        } else {
            if (null != bitmap) {
                wxMediaMessage.setThumbImage(getWxShareBitmap(bitmap))
            } else {
                val defaultBitmap = BitmapFactory.decodeResource(context?.resources, R.drawable.share_default)
                defaultBitmap?.let { wxMediaMessage.setThumbImage(getWxShareBitmap(it)) }
            }
            wxMediaMessage.mediaObject = WXWebpageObject(shareEntity?.url)
        }
        return wxMediaMessage
    }

    /**
     * 分享大图
     */
    private fun shareBigImage(bitmap: Bitmap?) {
        if (null == bitmap) {
            shareCallback?.failed(channel, ShareConstant.SHARE_STATUS_FAILED, "本地图片加载失败")
            return
        }
        val wxMediaMessage = WXMediaMessage()
        wxMediaMessage.mediaObject = WXImageObject(bitmap)

        // todo 压缩图片
        var width = bitmap.width
        var height = bitmap.height
        while (width * height > THUMB_SIZE * THUMB_SIZE) {
            width /= 2
            height /= 2
        }
        val thumbBmp = Bitmap.createScaledBitmap(bitmap, width, height, true)
        try {
            val localByteArrayOutputStream = ByteArrayOutputStream()
            thumbBmp.compress(Bitmap.CompressFormat.JPEG, 85, localByteArrayOutputStream)
            wxMediaMessage.thumbData = localByteArrayOutputStream.toByteArray()
            localByteArrayOutputStream.close()
        } catch (e: Exception) {
        }

        val req = SendMessageToWX.Req()
        req.transaction = System.currentTimeMillis().toString()
        req.message = wxMediaMessage
        when (channel) {
            ShareConstant.SHARE_CHANNEL_WEIXIN_FRIEND -> req.scene = SendMessageToWX.Req.WXSceneSession
            ShareConstant.SHARE_CHANNEL_WEIXIN_CIRCLE -> req.scene = SendMessageToWX.Req.WXSceneTimeline
        }

        api?.sendReq(req)
    }

    fun onResp(errorCode: Int, errorMsg: String) {
        shareCallback?.let {
            when (errorCode) {
                ShareConstant.SHARE_STATUS_COMPLETE -> it.success(channel)
                ShareConstant.SHARE_STATUS_CANCEL -> it.failed(channel, errorCode, errorMsg)
                ShareConstant.SHARE_STATUS_FAILED -> it.cancel(channel)
            }
        }
        shareCallback = null
    }

    /**
     * 检查：未安装微信或者微信版本太低
     */
    private fun check(): Boolean {
        return api?.isWXAppInstalled ?: false && api?.wxAppSupportAPI ?: 0 >= Build.PAY_SUPPORTED_SDK_INT
    }

    /**
     * 加载本地图片
     */
    private fun getLocalBitmap(context: Activity?, localPath: String?): Bitmap? {
        if (localPath.isNullOrEmpty()) {
            return null
        }
        val file = File(localPath)
        if (file.exists()) {
            try {
                return BitmapFactory.decodeFile(localPath)
            } catch (error: OutOfMemoryError) {
                error.printStackTrace()
            }
        }
        return BitmapFactory.decodeResource(context?.resources, R.drawable.share_default)
    }

    /**
     * 微信分享图片不能超过64kb，特别坑...
     * @param targetBitmap bitmap
     * @return Bitmap
     */
    private fun getWxShareBitmap(targetBitmap: Bitmap): Bitmap {
        val scale = (150.toFloat() / targetBitmap.width).coerceAtMost(150.toFloat() / targetBitmap.height)
        return Bitmap.createScaledBitmap(targetBitmap, (scale * targetBitmap.width).toInt(), (scale * targetBitmap.height).toInt(), false)
    }
}